﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using MethodWorx.CMS.Providers;
using MethodWorx.CMS.Services;
using MethodWorx.Core.DomainModel;
using MethodWorx.CMS.Content;
using MethodWorx.Core.Extensions;
using MethodWorx.CMS.TemplateLanguage;
using MethodWorx.CMS.Administration;
using MethodWorx.CMS.Plugins;
using MethodWorx.CMS.Workflow;
using MethodWorx.CMS.TemplateParser;

namespace MethodWorx.CMS.UI.Areas.Application.Models
{
    public class TemplateModel : ITemporaryTemplateStorage
    {
        private SchemaService schema;
        private PageTemplate pageTemplate;
        private IApplicationSettingsRepository applicationSettings;
        private PluginFactory plugins;
        private HttpSessionStateBase session;
        private ICmsDataProvider provider;

        public TemplateModel(ICmsDataProvider provider, SchemaService schema, IApplicationSettingsRepository applicationSettings, PluginFactory plugins, HttpSessionStateBase session)
        {
            this.schema = schema;
            this.applicationSettings = applicationSettings;
            this.plugins = plugins;
            this.session = session;
            this.provider = provider;
        }

        public void Initialize(Guid id)
        {
            this.pageTemplate = this.GetPageTemplate(id);


            this.Id = pageTemplate.Id;
            this.GetCode(id);
            this.Name = pageTemplate.Name;

            this.Templates = this.GetTemplates(pageTemplate);
            //this.Templates.First().Name += "&nbsp;-&nbsp;[Current]";
        }

        private void GetCode(Guid id)
        {
            this.Code = ((string)session["TemporaryTemplate:" + id]) ?? pageTemplate.Template ?? "";
        }

        private PageTemplate GetPageTemplate(Guid id)
        {
            var pageTemplate = this.schema.GetPageTemplateById(id);
            if (pageTemplate == null)
                throw new BusinessRuleException("Page Template Not Found");

            return pageTemplate;
        }

        private IEnumerable<PageTemplate> GetTemplates(PageTemplate template)
        {
            while (template != null)
            {
                yield return template;
                template = template.Parent;
            }
        }


        public Guid Id { get; private set; }
        public string Code { get; private set; }
        public string Name { get; private set; }
        public IParser[] Parsers { get; set; }
        public string[] ParserNamespaces { get; set; }
        public IEnumerable<PageTemplate> Templates { get; private set; }

        public IEnumerable<string> Placeholders
        {
            get
            {
                if(this.PageTemplate.Parent != null)
                {
                    var parser = new XmlParser(this.PageTemplate.Parent.Template);
                    foreach (var element in parser.Document.FlattenNodes<TemplateElement>())
                    {
                        if (element.Name.ToLower() == "placeholder" && element.GetAttributeValue("type", "", true) == "container")
                        {
                            var s = element.GetAttributeValue("name", "", true);
                            if (!string.IsNullOrEmpty(s))
                                yield return s;
                        }
                    }
                }
            }
        }

        public string GetParserName(string parser)
        {
            return parser.FirstCharToUpper();
        }

        public string GetParsedTemplate(string urlRoute)
        {
            ParsingEngine engine = new ParsingEngine(this.provider, this.pageTemplate, this.plugins, this);
            
            return engine.GetTemplateForDesignMode();




        }

        public void Complete(string code)
        {
            this.schema.SaveTemplate(this.pageTemplate, code);
            session["TemporaryTemplate:" + this.pageTemplate.Id] = null;
        }

        public PageTemplate PageTemplate { get { return this.pageTemplate; } }

        public ParsingEngine GetTemplateParser()
        {
            ParsingEngine engine = new ParsingEngine(this.provider, this.pageTemplate, this.plugins, this);
            engine.GetTemplateForDesignMode();

            return engine;
        }

        public string GetTemplateFromStorage(PageTemplate fromDatabase)
        {
            if(session["TemporaryTemplate:" + fromDatabase.Id] == null)
            {
                session["TemporaryTemplate:" + fromDatabase.Id] = fromDatabase.Template;
            }
            return (string)session["TemporaryTemplate:" + fromDatabase.Id];
        }

        internal void TemporarySaveTemplate(Guid templateId, string template)
        {
            session["TemporaryTemplate:" + templateId] = template;
        }

        internal void SaveFromDesigner()
        {
            foreach(var template in this.Templates)
            {
                if(session["TemporaryTemplate:" + template.Id] != null)
                {
                    this.schema.SaveTemplate(template, (string) session["TemporaryTemplate:" + template.Id]);
                    session["TemporaryTemplate:" + template.Id] = null;
                }
            }
        }
    }
}
